From 41881805d14ab2f2852c0f9410eb3c210681e905 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Mon, 26 Feb 2007 09:59:33 +0000 Subject: [PATCH] Write Xen ELF notes into xenstore on domain build. Signed-off-by: Brendan Cully --- tools/libxc/xc_dom_compat_linux.c | 25 ++++++++++++ tools/libxc/xenguest.h | 14 +++++++ tools/python/xen/lowlevel/xc/xc.c | 54 ++++++++++++++++++++----- tools/python/xen/xend/XendDomainInfo.py | 23 ++++++++++- xen/arch/x86/domain_build.c | 1 + xen/common/libelf/libelf-dominfo.c | 5 +++ xen/include/public/elfnote.h | 5 +++ xen/include/public/libelf.h | 18 ++++++++- 8 files changed, 134 insertions(+), 11 deletions(-) diff --git a/tools/libxc/xc_dom_compat_linux.c b/tools/libxc/xc_dom_compat_linux.c index d19a57d6b9..89265a6b37 100644 --- a/tools/libxc/xc_dom_compat_linux.c +++ b/tools/libxc/xc_dom_compat_linux.c @@ -122,6 +122,31 @@ int xc_linux_build(int xc_handle, uint32_t domid, return rc; } +int xc_dom_linux_build(int xc_handle, + struct xc_dom_image *dom, + uint32_t domid, + unsigned int mem_mb, + const char *image_name, + const char *initrd_name, + unsigned long flags, + unsigned int store_evtchn, + unsigned long *store_mfn, + unsigned int console_evtchn, unsigned long *console_mfn) +{ + int rc; + + if ( (rc = xc_dom_kernel_file(dom, image_name)) != 0 ) + return rc; + if ( initrd_name && strlen(initrd_name) && + ((rc = xc_dom_ramdisk_file(dom, initrd_name)) != 0) ) + return rc; + + return xc_linux_build_internal(dom, xc_handle, domid, + mem_mb, flags, + store_evtchn, store_mfn, + console_evtchn, console_mfn); +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h index 2f0bb4234d..cb3c6a4d1c 100644 --- a/tools/libxc/xenguest.h +++ b/tools/libxc/xenguest.h @@ -91,6 +91,20 @@ int xc_linux_build(int xc_handle, unsigned int console_evtchn, unsigned long *console_mfn); +/** The same interface, but the dom structure is managed by the caller */ +struct xc_dom_image; +int xc_dom_linux_build(int xc_handle, + struct xc_dom_image *dom, + uint32_t domid, + unsigned int mem_mb, + const char *image_name, + const char *ramdisk_name, + unsigned long flags, + unsigned int store_evtchn, + unsigned long *store_mfn, + unsigned int console_evtchn, + unsigned long *console_mfn); + /** * This function will create a domain for a paravirtualized Linux * using buffers for kernel and initrd diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 9b11b3c5f4..f4f3c47f3b 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -18,6 +18,8 @@ #include #include "xenctrl.h" +#include +#include "xc_dom.h" #include #include @@ -371,13 +373,17 @@ static PyObject *pyxc_linux_build(XcObject *self, PyObject *args, PyObject *kwds) { - uint32_t dom; + uint32_t domid; + struct xc_dom_image *dom; char *image, *ramdisk = NULL, *cmdline = "", *features = NULL; int flags = 0; int store_evtchn, console_evtchn; unsigned int mem_mb; unsigned long store_mfn = 0; unsigned long console_mfn = 0; + PyObject* elfnote_dict; + PyObject* elfnote = NULL; + int i; static char *kwd_list[] = { "domid", "store_evtchn", "memsize", "console_evtchn", "image", @@ -386,22 +392,52 @@ static PyObject *pyxc_linux_build(XcObject *self, "features", NULL }; if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list, - &dom, &store_evtchn, &mem_mb, + &domid, &store_evtchn, &mem_mb, &console_evtchn, &image, /* optional */ &ramdisk, &cmdline, &flags, &features) ) return NULL; - if ( xc_linux_build(self->xc_handle, dom, mem_mb, image, - ramdisk, cmdline, features, flags, - store_evtchn, &store_mfn, - console_evtchn, &console_mfn) != 0 ) { - return pyxc_error_to_exception(); + xc_dom_loginit(); + if (!(dom = xc_dom_allocate(cmdline, features))) + return pyxc_error_to_exception(); + + if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image, + ramdisk, flags, store_evtchn, &store_mfn, + console_evtchn, &console_mfn) != 0 ) { + goto out; } - return Py_BuildValue("{s:i,s:i}", + + if (!(elfnote_dict = PyDict_New())) + goto out; + for (i = 0; i < XEN_ELFNOTE_MAX; i++) { + switch (dom->parms.elf_notes[i].type) { + case XEN_ENT_NONE: + continue; + case XEN_ENT_LONG: + elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num); + break; + case XEN_ENT_STR: + elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str); + break; + } + PyDict_SetItemString(elfnote_dict, + dom->parms.elf_notes[i].name, + elfnote); + Py_DECREF(elfnote); + } + + xc_dom_release(dom); + + return Py_BuildValue("{s:i,s:i,s:N}", "store_mfn", store_mfn, - "console_mfn", console_mfn); + "console_mfn", console_mfn, + "notes", elfnote_dict); + + out: + xc_dom_release(dom); + return pyxc_error_to_exception(); } static PyObject *pyxc_hvm_build(XcObject *self, diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 615efbd56a..c0678b21ed 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -302,6 +302,8 @@ class XendDomainInfo: @type store_mfn: int @ivar console_mfn: xenconsoled mfn @type console_mfn: int + @ivar notes: OS image notes + @type notes: dictionary @ivar vmWatch: reference to a watch on the xenstored vmpath @type vmWatch: xen.xend.xenstore.xswatch @ivar shutdownWatch: reference to watch on the xenstored domain shutdown @@ -354,6 +356,7 @@ class XendDomainInfo: self.store_mfn = None self.console_port = None self.console_mfn = None + self.notes = {} self.vmWatch = None self.shutdownWatch = None @@ -776,13 +779,29 @@ class XendDomainInfo: def f(n, v): if v is not None: - to_store[n] = str(v) + if type(v) == bool: + to_store[n] = v and "1" or "0" + else: + to_store[n] = str(v) f('console/port', self.console_port) f('console/ring-ref', self.console_mfn) f('store/port', self.store_port) f('store/ring-ref', self.store_mfn) + # elfnotes + for n, v in self.notes.iteritems(): + n = n.lower().replace('_', '-') + if n == 'features': + for v in v.split('|'): + v = v.replace('_', '-') + if v.startswith('!'): + f('image/%s/%s' % (n, v[1:]), False) + else: + f('image/%s/%s' % (n, v), True) + else: + f('image/%s' % n, v) + to_store.update(self._vcpuDomDetails()) log.debug("Storing domain details: %s", scrub_password(to_store)) @@ -1462,6 +1481,8 @@ class XendDomainInfo: self.store_mfn = channel_details['store_mfn'] if 'console_mfn' in channel_details: self.console_mfn = channel_details['console_mfn'] + if 'notes' in channel_details: + self.notes = channel_details['notes'] self._introduceDomain() diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 841f181f99..3954e033a1 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -28,6 +28,7 @@ #include #include +#include #include extern unsigned long initial_images_nrpages(void); diff --git a/xen/common/libelf/libelf-dominfo.c b/xen/common/libelf/libelf-dominfo.c index 9425d85cc1..85a82f3bf5 100644 --- a/xen/common/libelf/libelf-dominfo.c +++ b/xen/common/libelf/libelf-dominfo.c @@ -119,13 +119,18 @@ int elf_xen_parse_note(struct elf_binary *elf, str = elf_note_desc(elf, note); elf_msg(elf, "%s: %s = \"%s\"\n", __FUNCTION__, note_desc[type].name, str); + parms->elf_notes[type].type = XEN_ENT_STR; + parms->elf_notes[type].data.str = str; } else { val = elf_note_numeric(elf, note); elf_msg(elf, "%s: %s = 0x%" PRIx64 "\n", __FUNCTION__, note_desc[type].name, val); + parms->elf_notes[type].type = XEN_ENT_LONG; + parms->elf_notes[type].data.num = val; } + parms->elf_notes[type].name = note_desc[type].name; switch ( type ) { diff --git a/xen/include/public/elfnote.h b/xen/include/public/elfnote.h index af50ba1f17..99f77593d3 100644 --- a/xen/include/public/elfnote.h +++ b/xen/include/public/elfnote.h @@ -156,6 +156,11 @@ */ #define XEN_ELFNOTE_L1_MFN_VALID 13 +/* + * The number of the highest elfnote defined. + */ +#define XEN_ELFNOTE_MAX XEN_ELFNOTE_L1_MFN_VALID + /* * System information exported through crash notes. * diff --git a/xen/include/public/libelf.h b/xen/include/public/libelf.h index 58598c8c09..59b8465108 100644 --- a/xen/include/public/libelf.h +++ b/xen/include/public/libelf.h @@ -174,12 +174,28 @@ int elf_reloc(struct elf_binary *elf); #define UNSET_ADDR ((uint64_t)-1) +enum xen_elfnote_type { + XEN_ENT_NONE = 0, + XEN_ENT_LONG = 1, + XEN_ENT_STR = 2 +}; + +struct xen_elfnote { + enum xen_elfnote_type type; + const char *name; + union { + const char *str; + uint64_t num; + } data; +}; + struct elf_dom_parms { /* raw */ const char *guest_info; const void *elf_note_start; const void *elf_note_end; - + struct xen_elfnote elf_notes[XEN_ELFNOTE_MAX + 1]; + /* parsed */ char guest_os[16]; char guest_ver[16]; -- 2.30.2